/*
 * EvolutiveCaseGenerator.h
 *
 *  Created on: 29/05/2011
 *      Author: godinho
 */

#ifndef EVOLUTIVECASEGENERATOR_H_
#define EVOLUTIVECASEGENERATOR_H_

#include "CaseGenerator.h"
#include <evolutive/FitnessFunction.h>
#include <evolutive/LifeSimulator.h>
#include <evolutive/CaseSelector.h>
#include <evolutive/OffspringGenerator.h>
#include <controller/CaseRecycler.h>
#include <localview/LocalView.h>
#include <evolutive/EventListener.h>

namespace localview {
class LocalView;
}

/**
 * Default concrete implementation of CaseGenerator.
 *
 * Objects of this class delegates some tasks to implementations of the following
 * classes:
 *
 * <ul>
 *   <li>FitnessFunction: calculates an individual fitness</li>
 *   <li>LifeSimulator: Uses simulation to generate parameters for FitnessFunction.
 *   	 (TODO LifeSimulator and FitnessFunction should be the same class, there
 *   	 are no reason to separate it in two classes).</li>
 *   <li>CaseSelector: based on fitness value, this objects pick up individuals
 *   	 for combination.</li>
 *   <li>OffspringGenerator: combine two or more individuals.</li>
 * </ul>
 */
class EvolutiveCaseGenerator: public CaseGenerator {
public:
	EvolutiveCaseGenerator();
	virtual ~EvolutiveCaseGenerator();

	/**
	 * @override
	 */
	virtual void startEvolution(std::vector<Case*> cases, int phaseId);

	/**
	 * @override
	 */
	virtual std::vector<Case*> getCases();

	/**
	 * @override
	 */
	void setTimedOut();

	void setFitnessFunction(FitnessFunction* fitnessFunction);

	void setLifeSimulator(LifeSimulator* lifeSimulator);

	void setCaseSelector(CaseSelector* selector);

	void setOffspringGenerator(OffspringGenerator* offspringGenerator);

	FitnessFunction* getFitnessFunction();

	LifeSimulator* getLifeSimulator();

	CaseSelector* getCaseSelector();

	OffspringGenerator* getOffspringGenerator();

	bool timedOut();

	void setEventListener(EventListener* listener);

	virtual void setLocalview(localview::LocalView* lv);

	void setNumInterations(int num);

private:
	/**
	 * Marks cases as dead to recycle.
	 */
	void killGeneration(std::vector<Case*> cases);

private:
	EventListener* mListener;
	FitnessFunction* mFitnessFunction;
	LifeSimulator* mLifeSimulator;
	CaseSelector* mCaseSelector;
	OffspringGenerator* mOffspringGenerator;
	CaseRecycler* mRecycler;
	localview::LocalView* mLocalview;
	std::vector<Case*> mParents;
	std::vector<Case*> mChildren;
	bool mEndIterations;
	int mNumIterations;
};

#endif /* EVOLUTIVECASEGENERATOR_H_ */
